Last update: June 2019
FlashAir supports the execution of programs written in Lua, which allows a lot of advanced features such as:
Lua scripting is available in Firmware Versions 3.00.00+.
Lua is a powerful, fast, lightweight, embeddable scripting language.
Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode for a register-based virtual machine, and has automatic memory management with incremental garbage collection - making it ideal for configuration, scripting, and rapid prototyping.
For more about the Lua language, see:
The following library functions are available in FlashAir Lua scripting:
The following functions in the standard library are not available because of the memory limitations:
Function Name | Description | Firmware Versions |
---|---|---|
Bridge | Enables Wireless LAN in Internet passthrough mode. | 3.00.00+ |
Connect | Enables Wireless LAN in STA mode. | 3.00.00+ |
ConnectedSTA | Number of connected stations at AP connection. | 4.00.00+ |
control("fioget") | Get wireless LAN On/Off status. | 4.00.00+ |
control("fioset") | Wireless LAN On/Off. | 4.00.00+ |
control("hid_change_pass") | Changing the password set for saving to the hidden area | 4.00.03+ |
control("hid_clear") | Delete all script files saved by password, API | 4.00.03+ |
control("hid_get") | Retrieve script saved in confidential area | 4.00.03+ |
control("hid_hash") | Create a hash string from the set password and the specified character string | 4.00.03+ |
control("hid_set_pass") | Set password for saving to hidden area | 4.00.03+ |
control("hid_store") | Save script to hidden area | 4.00.03+ |
control("time") | Save date and time memo. | 4.00.00+ |
Disconnect | Disables Wireless LAN. | 3.00.00+ |
Establish | Enables Wireless LAN in AP mode. | 3.00.00+ |
ftp | Downloads or upload a file by FTP. | 3.00.00+ |
GetScanInfo | Gets results of SSID scan. | 3.00.00+ |
hash | Generates hash. | 3.00.00+ |
HTTPGetFile | Downloads a file by HTTP. | 3.00.00+ |
Update i2c | I 2C operation. | 4.00.00+ |
ip | Gets or sets IP Address. | 3.00.00+ |
Update MailSend | Sends email by FlashAir. | 3.00.01+ |
deleted md5 | Generates MD5. | 3.00.00 |
ping | Issue PING to specified IP. | 3.00.00+ |
pio | Controls SD interface as a PIO. | 3.00.00+ |
New pwm("duty") | Set frequency and duty ratio at pwm operation | 4.00.03+ |
New pwm("init") | Enable pwm, set number of channels | 4.00.03+ |
New pwm("start") | Operate specified channel at pwm operation | 4.00.03+ |
New pwm("stop") | Stop specified channel at pwm operation | 4.00.03+ |
ReadStatusReg | Gets the status register contents of the FlashAir. | 3.00.00+ |
remove | Removes a file. | 3.00.00+ |
rename | Renames a file. | 3.00.00+ |
Updated request | Issues an HTTP Request. | 3.00.00+ |
Scan | Scans SSID. | 3.00.00+ |
search | File search function. | 4.00.00+ |
New serial("init") | Enable serial, set baudrate | 4.00.03+ |
New serial("read") | Receive data during serial operation | 4.00.03+ |
New serial("write") | Send data during serial operation | 4.00.03+ |
SetCert | Sets root certification by file. | 3.00.00+ |
SetChannel | Sets the wireless channels. | 3.00.01+ |
sharedmemory | Gets data from shared memory or writes data to shared memory. | 3.00.00+ |
sleep | Stops execution of the script during the specified timespan. | 3.00.00+ |
spi | Sets the SPI by FlashAir. | 3.00.01+ |
spi("bit") | Specify the number of transfer bits | 4.00.03+ |
spi("cs") | Control of chip select signal | 4.00.03+ |
spi("init") | Initialize the interface and change the clock cycle | 4.00.03+ |
spi("mode") | SPI mode specification | 4.00.03+ |
spi("read") | Write and read | 4.00.03+ |
spi("write") | Write and read | 4.00.03+ |
strconvert | Converts the string. | 3.00.00+ |
watchdog("event") | WatchDog timer reset | 4.00.03+ |
watchdog("start") | WatchDog timer start | 4.00.03+ |
watchdog("status") | Get state of WatchDog | 4.00.03+ |
watchdog("stop") | WatchDog timer stop | 4.00.03+ |
websocket | WebSocket function. | 4.00.00+ |
WlanLink | Confirms the connection. | 3.00.00+ |
Enables Wireless LAN in Internet passthrough mode.
fa.Bridge(ssid, networkkey, encmode, brgssid, brgnetworkkey)
None.
Enables Wireless LAN in STA mode.
fa.Connect(ssid, networkkey)
None.
Returns the number of connected stations at the time of AP connection, ip, mac.
cnt,tbl = fa.ConnectedSTA()
local cnt, tbl = fa.ConnectedSTA()
print(cnt,tbl)
for i,t in ipairs(tbl) do
for k,v in pairs(t) do
print(k,v)
end
end
1 table: 856B1C
mac 40:48:0f:7b:37:92
ip 192.168.0.11
Get on/off state of wireless LAN.
result = fa.control("fioget")
Turn on / off the wireless LAN.
result = fa.control("fioset", enable)
Change the password set for the hidden area.
ret = fa.control("hid_change_pass", old_password, new_password)
0
1
-1
Delete all script files saved by password, API.
fa.control("hid_clear")
None.
Get the script saved in the hidden area.
fa.control("hid_get", filename , dstfilename, password)
None.
fa.control("hid_get", "h:sys.lua", "tmp/option.lua", "mysecret")
Create a hash string from the password set in the hidden area and the specified character string.
ret = fa.control("hid_hash", string)
Sets the password for the preservation of the secret area.
fa.control("hid_set_pass", password)
None.
Save the script to the hidden area.
fa.control("hid_store", filename, password)
None.
fa.control("hid_store", "test.lua", "12345678")
Set the saved file with CONFIG
LUA_RUN_SCRIPT=H:filename
LUA_SD_EVNET=H:filename
Saves or acquires the date and time memo.
result = fa.control("time"[, savetime])
result = fa.control("time", 0x4ac1645c)
result = fa.control("time")
if result ~= nil then
print(string.format("time: 0x%08x", result))
end
Disables Wireless LAN.
fa.Disconnect()
None.
None.
Enables Wireless LAN in AP mode.
fa.Establish(ssid, networkkey, encmode)
None.
Encmode must be one of the following values:
Value | Description |
---|---|
0
|
Open system, No encryption. |
1
|
Open system, WEP |
3
|
WPA-PSK、TKIP |
4
|
WPA-PSK、AES |
5
|
WPA2-PSK、TKIP |
6
|
WPA2-PSK、AES |
Download or upload a file via FTP (File Transfer Protocol).
result = fa.ftp(cmd, uri, filename)
"get"
"put"
1
nil
ftps://
. Both
implicit and explicit modes are available.result = fa.ftp("get", "ftp://user:pass@ftp.test.com:21/test.txt", "test.txt");
result = fa.ftp("put", "ftps://user:pass@ftp.test.com:990/test.txt;implicit", "test.txt");
result = fa.ftp("put", "ftps://user:pass@ftp.test.com:990/test.txt;explicit", "test.txt");
Gets results of SSID scan.
ssid, other = fa.GetScanInfo(num)
This command is unavailable if the wireless LAN is enabled (by Connect, Establish, or Bridge).
count = fa.Scan()
for i=0,count-1 do
ssid,other = fa.GetScanInfo(i)
for key, val in pairs(other) do
print(key, val)
end
end
Generates a hash value.
hash=fa.hash(name, data, key)
Downloads a file by HTTP.
result = fa.HTTPGetFile(uri, filepath [, user, pass])
1
nil
I 2C operation is done from FlashAir. i2c works as Master.
res, data1, data2, data3, ... = fa.i2c(table)
res, string = fa.i2c(table)
res, data, ctrl = fa.i2c{mode = "getpio"}
45
,
100
,
189
, and
400
.
100
is set when omitted.
10
is set.
"read"
and
"write"
. When
"read"
is specified, data is read from the connected device. If
"write"
is specified, data is sent to the connected device.
0
and
255
. For
"setpio"
, specify 0 or 1 to output PIO.
"binary"
, values from 1
to
16
can be specified. When type is "string"
, the minimum value is 1
and the
maximum value is memory dependent. By default, 1
is set.
"binary"
and
"string"
. By default,
"binary"
is set.
Device initialization | Send start condition | Send restart condition | Read data from connected device | Write data to connected device | Send a stop condition and close the connection |
4.00.03
PIO setting |
4.00.03
PIO acquisition |
|
---|---|---|---|---|---|---|---|---|
mode |
"init"
|
"start"
|
"restart"
|
"read"
|
"write"
|
"stop"
|
"setpio"
|
"getpio"
|
freq | Optional | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary |
timeout | Optional | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary |
address | Unnecessary | Required | Required | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary |
direction | Unnecessary | Required | Required | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary |
data | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Required | Unnecessary | Required | Unnecessary |
bytes | Unnecessary | Unnecessary | Unnecessary | Optional | Optional | Unnecessary | Unnecessary | Unnecessary |
type | Unnecessary | Unnecessary | Unnecessary | Optional | Unnecessary | Unnecessary | Unnecessary | Unnecessary |
ctrl | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Unnecessary | Required | Unnecessary |
Pull up SCL / SDA.
Pull down CLK.
4.00.03
D1 can be used with
"setpio"
/
"getpio"
.
"OK"
. On failure it returns other strings.
0
to
255
are stored. It is used only when data is read from the connected device and
type = "binary"
is specified.
type = "string"
is specified.
type = "getpio"
is specified.
0
is input, and
1
is output. It is used only when
type = "getpio"
is specified.
res = fa.i2c{mode = "init", freq = 100}
res = fa.i2c{mode = "start", address = 50, direction = "write"}
res = fa.i2c{mode = "restart", address = 50, direction = "read"}
res, data1, data2, data3, ... = fa.i2c{mode = "read", type = "binary"}
res, string = fa.i2c{mode = "read", type = "string"}
res = fa.i2c{mode = "write", data = 0}
res = fa.i2c{mode = "stop"}
res = fa.i2c{mode = "init", freq = 100}
res = fa.i2c{mode = "start", address = 50, direction = "read"}
res, r1, r2, r3, r4, r5 = fa.i2c{mode = "read", bytes = 5, type = "binary"}
res = fa.i2c{mode = "stop"}
res = fa.i2c{mode = "init", freq = 100}
res = fa.i2c{mode = "start", address = 50, direction = "write"}
res = fa.i2c{mode = "write", data = 0}
res = fa.i2c{mode = "restart", address = 50, direction = "read"}
res, data = fa.i2c{mode = "read", bytes = 1, type = "binary"}
fa.i2c{mode = "stop"}
res = fa.i2c {mode ="init", freq=100}
res = fa.i2c {mode ="setpio", data=1, ctrl=1} -- Output High
res = fa.i2c {mode ="setpio", data=0, ctrl=1} -- Output Low
res = fa.i2c {mode ="setpio", data=0, ctrl=0} -- Input
res, data, ctrl = fa.i2c {mode="getpio"}
Gets or sets IP Address of FlashAir.
ip, mask, gw = fa.ip(ipaddress, subnetmask, gateway)
-- When getting values
ip, mask, gw = fa.ip()
-- When setting values
fa.ip("192.168.11.2", "255.255.255.0", "192.168.11.1")
Sends email by FlashAir(enables to attach a file).
fa.MailSend(table)
Successful: MailSend is success.
Failure:
nil
(failed to send).
from = "fromaddr@yahoo.co.jp"
rcpt = "toaddr@gmail.com"
a = fa.MailSend {
from = from,
headers = "To: "..rcpt.."\r\nFrom: "..from.."\r\nSubject: test",
body = "HELLO HELLO",
server = "smtp.mail.yahoo.co.jp",
user = "flashair",
password ="1234567890",
attachment = "FBYF.jpg",
ContentType = "image/jpg"
}
This is obsolete. Use
hash
.
Issue PING to specified IP.
result = fa.ping(ip)
1
nil
result = fa.ping("192.168.130.1")
Controls the SD interface with PIO (Programmed Input/Output).
s, indata = fa.pio(ctrl, data)
0
for the bit corresponding to the pin to be read and
1
for the bit corresponding to the pin to be written.
0
is set for each bit corresponding to the pin to be written, Low is output, and when
it is set
to
1
, High is output.
1
0
Bit assignment.
Set the frequency and duty ratio when doing PWM operation with FlashAir.
res = fa.pwm("duty", ch, freq, duty)
0
~4
channels can be specified.
1
nil
Enable pwm and set the number of channels when using pwm with FlashAir.
ret = fa.pwm("init", ch, enable)
0
~4
channels can be specified.
1
nil
IFMODE=1
in CONFIG.Operates the specified channel when performing pwm operation with FlashAir. 0~4 channels can be specified.
res = fa.pwm("start", ch)
0
~4
channels can be specified.
1
nil
Stop the specified channel when performing pwm operation with FlashAir. 0~4 channels can be specified.
res = fa.pwm("stop", ch)
0
~4
channels can be specified.
1
nil
Gets the status register contents of the FlashAir.
reg = fa.ReadStatusReg()
None.
Returns the wireless LAN application status register contents as a string. Refer to Wireless LAN Application Status Register for details.
Get IP address of the card.
local ipaddress = string.sub(fa.ReadStatusReg(),160,168)
Removes a file.
fa.remove(filepath)
None.
fa.remove("/DCIM/100__TSB/DSC_100.JPG")
Moves or renames a file or a directory.
fa.rename(oldfile, newfile)
None.
fa.rename("/DCIM/100__TSB/DSC_100.JPG","/DCIM/100__TSB/DSC_101.JPG")
Issues an HTTP (Hyper Text Transfer Protocol) request.
b, c, h = fa.request(url [, method [, headers [, file [, body [, bufsize [, redirect [, rcvbuff [, rcvfile]]]]]]]])
"GET"
is used if a method not specified.
table. You can add header field information for HTTP requests.
string. Add the specified file to the body of the HTTP request and send it.
string. It adds the specified character string to the body of the HTTP request and sends
it. When
used in conjunction with the file option, it replaces the character string inside the body
<!--WLANSDFILE-->
with a file and sends it. If body is not specified, just
file will be
sent.
number. Transmit buffer size of HTTP request. When sending to flickr server, set this value to 1460 * 10.
boolean. Controls validity / invalidity of redirect operation of HTTP. If you omit it is
assumed
to be specified
true
.
string. Secure memory on Lua's stack and save the received data in secured memory.
string. It saves the received HTTP response data to the specified file.
boundary = "--61141483716826"
contenttype = "multipart/form-data; boundary=" .. boundary
filepath = "sample.txt"
mes = "--".. boundary .. "¥r¥n"
.."Content-Disposition: form-data; name=¥"file¥"; filename=¥""..file .."¥"¥r¥n"
.."Content-Type: text/plain¥r¥n"
.."¥r¥n"
.."<!--WLANSDFILE-->¥r¥n"
.."--" .. boundary .. "--¥r¥n"
blen = lfs.attributes(file,"size") + string.len(mes) - 17
b,c,h = fa.request{url = "http://192.168.0.1/upload.cgi:8080",
method = "POST",
headers = {["Content-Length"] = tostring(blen),
["Content-Type"] = contenttype},
file = filepath,
body = mes
}
Scans SSID. Call GetScanInfo() to retrieve scan results.
count = fa.Scan([ssid])
This command is unavailable if the wireless LAN is enabled (by Connect, Establish, or Bridge).
It searches for files based on the updated date and time in the specified directory. It is possible to search for a file whose with the latest date and time, or to search for a file with the update date specified by argument.
result, filelist, time = fa.search(type, path, searchtime)
1 | Successful |
---|---|
-1 | Overflow when creating file list
|
-2 | Overflow at creation of file list (There is a possibility of returning it only when
specifying
-1 for searchtime)
|
-3 | Directory open error |
-4 | Directory read error |
local result, filelist, time = fa.search("file", "/DCIM", -1)
if result ~= 1 then
print("error: ", result)
end
if filelist ~= nil then
for f in string.gmatch(filelist, '(.-),') do
print(f)
end
end
if time ~= nil then
print(string.format("time: 0x%08x", time))
end
local result, filelist, time = fa.search("file", "/DCIM", 0x4ac1645c)
if result ~= 1 then
print("error: ", result)
end
if filelist ~= nil then
for f in string.gmatch(filelist, '(.-),') do
print(f)
end
end
if time ~= nil then
print(string.format("time: 0x%08x", time))
end
local function StringToFatDateTime(datetime_str)
local pattern = '(%d+)/(%d+)/(%d+)%s+(%d+):(%d+):(%d+)'
local year,month,day,hour,min,sec = string.match(datetime_str, pattern)
year = year - 1980
sec = bit32.rshift(sec, 1)
local date_fat = bit32.bor(bit32.lshift(year, 9),
bit32.lshift(month, 5),
day)
local time_fat = bit32.bor(bit32.lshift(hour, 11),
bit32.lshift(min, 5),
sec)
local datetime_fat = bit32.bor(bit32.lshift(date_fat, 16),
time_fat)
return datetime_fat
end
local function FatDateTimeToString(datetime_fat)
local function getbits(x, from, to)
local mask = bit32.lshift(1, to - from + 1) - 1
local shifted = bit32.rshift(x, from)
return bit32.band(shifted, mask)
end
local fatdate = bit32.rshift(datetime_fat, 16)
local day = getbits(fatdate, 0, 4)
local month = getbits(fatdate, 5, 8)
local year = getbits(fatdate, 9, 15) + 1980
local fattime = getbits(datetime_fat, 0, 15)
local sec = getbits(fattime, 0, 4) * 2
local min = getbits(fattime, 5, 10)
local hour = getbits(fattime, 11, 15)
return string.format('%02d/%02d/%02d %02d:%02d:%02d', year, month, day, hour, min, sec)
end
Set serial enable and baudrate when using serial operation with FlashAir.
fa.serial("init", [boudrate])
None
IFMODE=1
in CONFIG.Receive data when performing serial operation with FlashAir.
data = fa.serial("read")
None
nil
is returned.
Send data when using performing serial operation with FlashAir.
fa.serial("write", data)
None
Sets or clears root certification by file(X.509 binary encode with DER).
fa.SetCert(filename)
1
nil
-- Certificate registration
res = fa.SetCert("DerSha256.cer")
if res == nil then
print("certificate registration error")
end
-- Clear certificate
res = fa.SetCert("")
if res == nil then
print("certificate clear error")
end
Sets the wireless channels.
fa.SetChannel(channelNo)
None.
fa.Disconnect()
fa.SetChannel("0xB")
fa.Establish("flashair3", "12345678", "6")
Gets data from shared memory or writes data to shared memory.
4.00.03 Added support for write and read null characters.
fa.sharedmemory(command, addr, len, wdata)
write ⇒ Failure:
nil
Successful:
1
read ⇒ Failure:
nil
Successful: the string of read data
res1 = fa.sharedmemory("write", 0, 8, "12345678")
res2 = fa.sharedmemory("read", 1, 4, 0)
print("res=",res2)
Result:res=2345
Stops execution of the script during the specified timespan.
sleep(msec)
None.
Sets the SPI by FlashAir.
fa.spi(command,data)
Bit Allocation
write | :The received data when
write
command was issued. |
read | :The read data when
read
command was issued. |
otherwise | :Any status. |
fa.spi("init", 1001)
Sets the number of transfer bits. (Default value: 8)
res = fa.spi("bit", bit)
1
~
32
. Number of transfer bits.
1
0
When specifying a character string with spi("write"), it can not be used with bit specification.
Controls the chip select signal.
fa.spi("cs", cs_level)
local CS_ASSERT=0
local CS_NEGATE=1
fa.spi("mode", 2)
fa.spi("init", 1000)
fa.spi("cs", CS_ASSERT)
fa.spi("write", "hello", 5)
fa.spi("cs", CS_NEGATE)
Initialize the interface and change the clock cycle (default value: 1000). CS becomes High.
res = fa.spi("init"[, period])
1
0
Sets the SPI mode. (Default value: 3)
res = fa.spi("mode", mode)
0
~
3
. SPI mode.
1
0
Execute spi("mode") before executing spi("init").
Write and read. It can rotate multiple times and get all lead results. Transmission data transmits fixed value repeatedly.
res_num = fa.spi("read")
res_tbl = fa.spi("read", xfer_num, data_num)
In Syntax of fa.spi("read"), all 0s are transmitted.
In Syntax of fa.spi("read", xfer_num, data_num), data_num is sent repeatedly.
res_num = fa.spi("read")
print(res_num)
res_tbl = fa.spi("read", 10, 0xff)
for i, v in ipairs(res_tbl) do
print(i, v)
end
Write and read. Although it can be transferred more than once, the read result can be acquired only once last.
res = fa.spi("write", data_num)
res = fa.spi("write", data_str, xfer_num)
res = fa.spi("write", 0x12)
result = fa.spi("write", "hello", 8)
When data_str is used, it can not be used with bit specification.
Converts the SJIS characters to UTF-8 , and the utf8 characters to SJIS.
fa.strconvert(format, orgstr)
Successful: Converted strings.
Failure:
nil
str = "あかさたなはまやらわ"
print("testStr=", str)
a = fa.strconvert("sjis2utf8", str )
print("toUTF8=", a)
b = fa.strconvert("utf82sjis", a)
print("toSJIS=", b)
Reset the timer of WatchDog.
result = fa.watchdog("event")
1
0
Start the timer of WatchDog. FlashAir restarts when it times out.
result = fa.watchdog("start", cycle)
1
0
WatchDog is a timer to ensure that the system will continue to function correctly. If an abnormal situation occurs in the system after starting the WatchDog timer and it is not able to be reset, restarting FlashAir is the proper course of action.
Example
LUA_RUN_SCRIPT=/HelloWorld.lua
to the CONFIG file. Save
HelloWorld.lua
used in
this
tutorial on the FlashAir route. If you already have Hello.txt on the route please rename or
delete it.
fa.watchdog("start", 10)
print("watchdog start")
for i = 1, 30 do
result = fa.watchdog("status")
print("watchdog status:"..result)
end
result, filelist, time = fa.search("file", "/DCIM", -1)
if filelist ~= nill then
result = fa.watchdog("event")
print("watchdog restart")
else
fa.watchdog("stop")
print("watchdog stop")
end
while 0 ~= fa.watchdog("status") do
result = fa.watchdog("status")
print("watchdog status:"..result)
end
This script starts the Watchdog timer at 10 second intervals, checks the Watchdog status several
times,
restarts the Watchdog timer when there is
/DCIM
, and also continues printing until the Watchdog status is 0.
HelloWorld.lua
. (Hello There! Should be displayed on one line)
WatchDog.lua
from your browser.
LUA_RUN_SCRIPT
is running.
Get the state of WatchDog.
result = fa.watchdog("status")
0
or more
0
-1
Stop the WatchDog timer.
result = fa.watchdog("stop")
0
WebSocket communication.
res, type, payload = fa.websocket(table)
1
, binary =
2
, PING =
9
, default = automatic determination).
open | Send Messege | Receive message | Close | |
---|---|---|---|---|
mode |
"open"
|
"send"
|
"recv"
|
"close"
|
address | Required | Unnecessary | Unnecessary | Unnecessary |
payload | Unnecessary | Required | Unnecessary | Unnecessary |
type | Unnecessary | Optional | Unnecessary | Unnecessary |
length | Unnecessary | Optional | Unnecessary | Unnecessary |
tout | Unnecessary | Unnecessary | Optional | Unnecessary |
0
or positive number is returned. When reception fails, it returns a negative number.
1
, binary =
2
). It is used only when receiving a message.
nil
is returned. It is used only when receiving a message.
res = fa.websocket{mode = "open", address = "ws://localhost/socket"}
res = fa.websocket{mode = "send", payload = "hello!", type = 1}
res, type, payload = fa.websocket{mode = "recv", tout = 5000}
fa.websocket{mode = "close"}
Confirms the FlashAir is wirelessly connected to the network.
result = fa.WlanLink()
None.
1
0
You can access the second partition. The second partition is an area where Lua's internal logs are
saved and
there is no effect from file access from the host device.
It is possible to specify the partition by the drive letter.
"p" --1st partition (omitted)
"s" --2nd Partition
"h" --Secret area
Partition creation can be divided using host equipment such as Linux, Win10.
local file = io.open("s:\flashair.log", "a")